#!/usr/bin/env python
# -*- coding: utf-8 -*-

import hashlib
import threading

from sqlalchemy import orm

from farado.logger import logger
from farado.helpers.long_action_watcher import LongActionWatcher



class User(LongActionWatcher):
    def base_init(self):
        LongActionWatcher.__init__(self)

        # Статус пользователя
        self.online_state = False

        # Гарант потокобезопасности экземпляра класса
        self.mutex = threading.RLock()

        # Словарь параметров для последнего действия пользователя
        self._last_action_data = None

        # Результат выполнения последнего действия пользователя
        self._last_action_result = None

    def __init__(
            self,
            login="",
            first_name="",
            middle_name="",
            last_name="",
            email="",
            password_hash=None,
            password=None,
            need_change_password=False,
            more_info="",
            is_blocked=False,
            ):
        self.base_init()
        self.id = None
        self.login = login
        self.first_name = first_name
        self.middle_name = middle_name
        self.last_name = last_name
        self.email = email
        self.need_change_password = need_change_password
        self.more_info = more_info
        self.is_blocked = is_blocked

        if password_hash:
            self.password_hash = password_hash
        elif password:
            self.set_password(password)

    @orm.reconstructor
    def init_on_load(self):
        '''Данный конструктор вызывается при создании объекта через sqlalchemy'''
        self.base_init()

    def __repr__(self):
        with self.mutex:
            return str(
                f'''<User(id='{ self.id
                    }',\n login='{ self.login
                    }',\n first_name='{ self.first_name
                    }',\n middle_name='{ self.middle_name
                    }',\n last_name='{ self.last_name
                    }',\n email='{ self.email
                    }',\n password_hash='{ self.password_hash
                    }',\n need_change_password='{ self.need_change_password
                    }',\n more_info='{ self.more_info
                    }',\n is_blocked='{ self.is_blocked
                    }',\n online_state='{ self.online_state
                    }')>'''
                )

    def set_password(self, password):
        with self.mutex:
            self.password_hash = hashlib.sha256(password.encode('utf-8')).hexdigest()
            logger.info(f'Изменён пароль пользователя {self.login}.')

    def check_password(self, password):
        with self.mutex:
            return bool(self.password_hash == hashlib.sha256(password.encode('utf-8')).hexdigest())

    def push_last_action_data(self, data):
        with self.mutex:
            self._last_action_data = data

    def pop_last_action_data(self):
        with self.mutex:
            data = self._last_action_data
            self._last_action_data = None
        return data

    def push_last_action_result(self, result):
        with self.mutex:
            self._last_action_result = result

    def pop_last_action_result(self):
        with self.mutex:
            result = self._last_action_result
            self._last_action_result = None
        return result
